package com.coffee.mybatis;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Songkui
 * @since 2019/10/29 9:30
 */
public class CodeGenerator
{

    private static String projectPath = System.getProperty("user.dir") + "/mocha-basics-starter/mocha-mybatis-starter";
    private static String template = "/template";


    private InjectionConfig getInjectionConfig(PackageConfig pc)
    {
        String parent = pc.getParent();
        String replace = "";
        if (StrUtil.isNotBlank(parent))
        {
            replace = parent.replace(".", "/");
        }
        String srcJava = "/src/test/java/" + replace + "/";
        String srcRes = "/src/test/resources";

        // 自定义输出配置
        List<FileOutConfig> focList = new ArrayList<>();
        String templatePath = template + "/mapper.xml.ftl";
        // 自定义配置:mapper.xml
        focList.add(new FileOutConfig(templatePath)
        {
            @Override
            public String outputFile(TableInfo tableInfo)
            {
                // 自定义输出文件名
                return projectPath + srcRes + "/mapper/" + pc.getModuleName() +"/" + tableInfo.getXmlName() + StringPool.DOT_XML;
            }
        });

        // 自定义配置:controller.java
        templatePath = template + "/controller.java.ftl";
        focList.add(new FileOutConfig(templatePath)
        {
            @Override
            public String outputFile(TableInfo tableInfo)
            {
                // 自定义输出文件名
                return projectPath + srcJava + "/controller/" + tableInfo.getControllerName() + StringPool.DOT_JAVA;
            }
        });

        // 自定义配置:dao.java
        templatePath = template + "/mapper.java.ftl";
        focList.add(new FileOutConfig(templatePath)
        {
            @Override
            public String outputFile(TableInfo tableInfo)
            {
                // 自定义输出文件名
                return projectPath + srcJava + "/dao/" + tableInfo.getMapperName() + StringPool.DOT_JAVA;
            }
        });

        // 自定义配置:xxPo.java
        templatePath = template + "/entity.java.ftl";
        focList.add(new FileOutConfig(templatePath)
        {
            @Override
            public String outputFile(TableInfo tableInfo)
            {
                // 自定义输出文件名
                return projectPath + srcJava + "/entity/" + tableInfo.getEntityName() + StringPool.DOT_JAVA;
            }
        });


        // 自定义配置:xxService.java
        templatePath = template + "/Service.java.ftl";
        focList.add(new FileOutConfig(templatePath)
        {
            @Override
            public String outputFile(TableInfo tableInfo)
            {
                // 自定义输出文件名
                return projectPath + srcJava + "/service/" +
                        tableInfo.getServiceName() + StringPool.DOT_JAVA;
            }
        });

        // 自定义配置
        InjectionConfig cfg = new InjectionConfig()
        {
            @Override
            public void initMap()
            {
            }
        };
        cfg.setFileOutConfigList(focList);
        return cfg;
    }

    /**
     * 数据源配置
     *
     * @return com.baomidou.mybatisplus.generator.config.DataSourceConfig
     * @author LiuYongTao
     * @since 2019/10/29 9:10
     */
    private DataSourceConfig getDataSourceConfig()
    {
        DataSourceConfig dsc = new DataSourceConfig();
//        dsc.setDriverName("org.postgresql.Driver");
//
//        dsc.setUrl("jdbc:postgresql://192.168.50.149:5432/postgres");
//        dsc.setUsername("postgres");
//        dsc.setPassword("HYzh248713");
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUrl("jdbc:mysql://127.0.0.1:3306/coffee?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false" +
                "&allowPublicKeyRetrieval=true");
        dsc.setUsername("root");
        dsc.setPassword("mysql123");
        return dsc;
    }

    /**
     * 全局配置
     *
     * @return com.baomidou.mybatisplus.generator.config.GlobalConfig
     * @author LiuYongTao
     * @since 2019/10/29 9:07
     */
    private GlobalConfig getGlobalConfig()
    {
        GlobalConfig gc = new GlobalConfig();
        gc.setOutputDir(projectPath + "/src/test/java");
        gc.setAuthor("Songkui");
        gc.setOpen(false);
        gc.setBaseResultMap(true);
        gc.setBaseColumnList(true);
        gc.setFileOverride(true);
        gc.setEnableCache(true);

        gc.setIdType(IdType.ASSIGN_ID);

        gc.setServiceName("%sService");
        gc.setEntityName("%sEntity");
        gc.setControllerName("%sController");
        gc.setMapperName("%sDao");
        gc.setXmlName("%sMapper");
        return gc;
    }

    public void gen()
    {
        // 全局配置
        GlobalConfig gc = this.getGlobalConfig();
        // 数据源配置
        DataSourceConfig dsc = this.getDataSourceConfig();
        // 策略配置
        StrategyConfig strategy = this.getStrategyConfig();
        // 生成表配置
        this.setGenTableRule(strategy);
        // 包配置
        PackageConfig pc = this.getPackageConfig(strategy);
        // 自定义配置
        InjectionConfig cfg = this.getInjectionConfig(pc);

        // 代码生成器
        AutoGenerator mpg = new AutoGenerator();
        mpg.setGlobalConfig(gc)
                .setDataSource(dsc)
                .setStrategy(strategy)
                .setPackageInfo(pc)
                .setCfg(cfg);
        // 设置模板配置
        TemplateConfig templateConfig = new TemplateConfig();
        templateConfig.setXml(null)
                .setController(null)
                .setService(null)
                .setServiceImpl(null)
                .setEntity(null)
                .setMapper(null);
        // 设置模板
        mpg.setTemplate(templateConfig)
                // 设置模板引擎
                .setTemplateEngine(new FreemarkerTemplateEngine())
                .execute();
    }

    /**
     * 策略配置
     *
     * @return com.baomidou.mybatisplus.generator.config.StrategyConfig
     * @author LiuYongTao
     * @since 2019/10/29 9:20
     */
    private StrategyConfig getStrategyConfig()
    {
        StrategyConfig strategy = new StrategyConfig();
        strategy.setNaming(NamingStrategy.underline_to_camel);
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        // 公共父类
        strategy.setSuperEntityClass("com.scshyzh.mybatis.pojo.BaseEntity");
        strategy.setEntityLombokModel(true);
        strategy.setRestControllerStyle(true);
        // 是否为链式模型（默认 false）
        strategy.setChainModel(true);
        // 是否生成字段常量（默认 false）
//        strategy.setEntityColumnConstant(true);
        // 公共父类
//        strategy.setSuperControllerClass("com.baomidou.ant.common.BaseController");
        // 写于父类中的公共字段
        strategy.setSuperEntityColumns("creatorId", "create_time", "updater_id", "update_time", "status_bit");
        strategy.setControllerMappingHyphenStyle(true);
        strategy.setEntityBooleanColumnRemoveIsPrefix(true);
        strategy.setEntityTableFieldAnnotationEnable(true);
        return strategy;
    }


    /**
     * 包配置
     *
     * @return com.baomidou.mybatisplus.generator.config.PackageConfig
     * @author LiuYongTao
     * @since 2019/10/29 9:11
     */
    private PackageConfig getPackageConfig(StrategyConfig strategy)
    {
        PackageConfig pc = new PackageConfig();
        String parent = "";
        if (strategy.getTablePrefix().contains("pms_") || strategy.getTablePrefix().contains("sms_"))
        {
            parent = "product";
        }
        else if (strategy.getTablePrefix().contains("sk_"))
        {
            parent = "seckill";
        }
        else if (strategy.getTablePrefix().contains("sys_") || strategy.getTablePrefix().contains("v_"))
        {
            parent = "bss";
        }
        else if (strategy.getTablePrefix().contains("oms_"))
        {
            parent = "order";
        }
        else if (strategy.getTablePrefix().contains("u_"))
        {
            parent = "user";
        }
        else if (strategy.getTablePrefix().contains("lx_"))
        {
            parent = "lx";
        }
        else if (strategy.getTablePrefix().contains("bh_"))
        {
            parent = "bh";
        }
        else if (strategy.getTablePrefix().contains("buy_"))
        {
            parent = "buy";
        }

        pc.setParent("com.scshyzh");  // 这个提供外部修改
        pc.setModuleName(parent);
        pc.setEntity("entity");
        pc.setController("controller");
        pc.setMapper("dao");
        return pc;
    }

    /**
     * 表生成规则配置
     *
     * @param strategy
     * @author liuyongtao
     * @since 2021-9-8 8:26
     */
    private void setGenTableRule(StrategyConfig strategy)
    {
        //        strategy.setInclude("oms_cart_item"
//                , "oms_company_address"
//                , "oms_order"
//                , "oms_order_item"
//                , "oms_order_operate_history"
//                , "oms_order_return_apply"
//                , "oms_order_return_reason"
//                , "oms_order_setting");
//        strategy.setTablePrefix("oms_");



        strategy.setInclude(
                "sys_user"
        );
        //strategy.setTablePrefix("lx_");


//        strategy.setTablePrefix("u_");
//        strategy.setInclude("u_user"
//        );
    }

    public static void main(String[] args)
    {
        CodeGenerator cg = new CodeGenerator();
        cg.gen();
    }
}